<template>
  <div class="app-container">
    <h1>TableInfo</h1>
    <el-collapse v-model="activeName" accordion>
      <el-card class="box-card">
        <div slot="header" class="clearfix">
          <span>上传sql</span>
        </div>
        <el-upload
          class="upload-demo"
          drag
          :action="uploadUrl"
          :auto-upload="true"
          :accept="acceptList"
          @error="uploadError"
          :on-remove="handlerRemove"
          :before-upload="beforeUpload"
          :file-list="fileList"
        >
          <i class="el-icon-upload"></i>
          <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
          <div class="el-upload__tip" slot="tip">
            <el-tooltip class="item" effect="dark" content="请选择数据库类型用于生成正确的代码。数据库名称会根据上传的sql自动获取，请务必保证不包含中文字符" placement="top-start">
              <el-form :inline="true" :model="ruleForm" :rules="rules" ref="ruleForm">
              <el-row>
                <el-col :span="6">
                  <el-form-item label="数据库类型" prop="databaseType">
                    <el-select v-model="ruleForm.databaseType" placeholder="请选择数据库类型" clearable>
                      <el-option
                        v-for="item in databaseOptions"
                        :key="item.value"
                        :label="item.label"
                        :value="item.value"
                        :disabled="item.disabled">
                      </el-option>
                    </el-select>
                  </el-form-item>
                </el-col>
                <el-col :span="6">
                  <el-form-item label="数据库名称" prop="database">
                    <el-input v-model="ruleForm.database" placeholder="请输入数据库名称" clearable/>
                  </el-form-item>
                </el-col>
                <el-col :span="6">
                  <el-form-item label="序列号" prop="serialNumber">
                    <el-input v-model="ruleForm.serialNumber" placeholder="请输入生成序列号" clearable/>
                  </el-form-item>
                </el-col>
                <el-col :span="2">
                  <el-form-item>
                    <el-button type="primary" @click="doGenerate">生成</el-button>

                  </el-form-item>
                </el-col>
                <el-col :span="2">
                  <el-form-item>
                    <el-button type="primary" @click="doParse">解析</el-button>
                  </el-form-item>
                </el-col>
              </el-row>
            </el-form>
            </el-tooltip>
          </div>
        </el-upload>
      </el-card>
      <el-card class="box-card">
        <div slot="header" class="clearfix">
          <span>数据库解析结果</span>
        </div>
        <el-collapse-item title="公共参数" name="1">
          <el-card class="box-card">
            <div slot="header" class="clearfix">
              <span>公共参数</span>
              <el-button style="float: right;" type="primary" @click="addProperty" size="mini">添加</el-button>
            </div>
            <el-table
              style="width: 100%"
              :data="commonProperties"
            >
              <el-table-column type="index" label="序号" width="100" />
              <el-table-column prop="columnName" label="属性名" width="150">
                <template slot-scope="scope">
                  <el-input v-model="scope.row.columnName" autocomplete="off" size="small"
                            placeholder="属性名" @change="changeJavaType(scope.$index,scope.row)"></el-input>
                </template>
              </el-table-column>
              <el-table-column prop="dataType" label="数据库类型" width="150">
                <template slot-scope="scope">
                  <el-input v-model="scope.row.dataType" autocomplete="off" size="small"
                            placeholder="请输入数据库类型"></el-input>
                </template>
              </el-table-column>
              <el-table-column prop="fieldType" label="java类型" width="150">
                <template slot-scope="scope">
                  <el-input v-model="scope.row.fieldType" autocomplete="off" size="small"
                            placeholder="请输入java类型" ></el-input>
                </template>
              </el-table-column>
              <el-table-column prop="fieldNme" label="字段名" width="150">
                <template slot-scope="scope">
                  <el-input v-model="scope.row.fieldName" autocomplete="off" size="small"
                            placeholder="请输入字段名" disabled></el-input>
                </template>
              </el-table-column>
              <el-table-column prop="defaultValue" label="默认值" width="200">
                <template slot-scope="scope">
                  <el-input v-model="scope.row.defaultValue" autocomplete="off" size="small"
                            placeholder="请输入默认值"></el-input>
                </template>
              </el-table-column>
              <el-table-column
                label="操作"
                width="180">
                <template slot-scope="scope">
                  <el-button size="mini" type="danger" plain @click="delProperty(scope.$index, scope.row)">删除</el-button>
                </template>
              </el-table-column>
            </el-table>
          </el-card>
        </el-collapse-item>
        <el-collapse-item title="表结构" name="2">
          <el-card class="box-card">
            <div slot="header" class="clearfix">
              <span>表结构</span>
              <el-button style="float: right;" type="primary" @click="addTable" size="mini">添加</el-button>
            </div>
            <el-table
              style="width: 100%"
              :data="tableList"
            >
              <el-table-column type="expand" width="100%">
                <template slot-scope="props">
                  <el-table
                    style="width: 100%"
                    :data="props.row.columnList"
                  >
                    <el-table-column type="index" label="序号" width="80" />
                    <el-table-column prop="isDateCol" label="是否主键" width="80">
                      <template slot-scope="scope">
                        <el-switch
                          v-model="scope.row.isKeyCol"
                          active-color="#13ce66"
                          inactive-color="#ff4949"
                        />
                      </template>
                    </el-table-column>
                    <el-table-column prop="columnName" label="属性名" width="180">
                      <template slot-scope="scope">
                        <el-input v-model="scope.row.columnName" autocomplete="off" size="small"
                                  placeholder="属性名" @change="changeJavaType(scope.$index,scope.row)"></el-input>
                      </template>
                    </el-table-column>
                    <el-table-column prop="dataType" label="数据库类型" width="150">
                      <template slot-scope="scope">
                        <el-input v-model="scope.row.dataType" autocomplete="off" size="small"
                                  placeholder="请输入数据库类型"></el-input>
                      </template>
                    </el-table-column>
                    <el-table-column prop="fieldType" label="java类型" width="150">
                      <template slot-scope="scope">
                        <el-input v-model="scope.row.fieldType" autocomplete="off" size="small"
                                  placeholder="请输入java类型" ></el-input>
                      </template>
                    </el-table-column>
                    <el-table-column prop="fieldNme" label="字段名" width="150">
                      <template slot-scope="scope">
                        <el-input v-model="scope.row.fieldName" autocomplete="off" size="small"
                                  placeholder="请输入字段名" disabled></el-input>
                      </template>
                    </el-table-column>
                    <el-table-column prop="defaultValue" label="默认值" width="150">
                      <template slot-scope="scope">
                        <el-input v-model="scope.row.defaultValue" autocomplete="off" size="small"
                                  placeholder="请输入默认值"></el-input>
                      </template>
                    </el-table-column>
                    <el-table-column prop="searchField" label="查询字段" width="80">
                      <template slot-scope="scope">
                        <el-switch
                          v-model="scope.row.searchField"
                          active-color="#13ce66"
                          inactive-color="#ff4949"
                        />
                      </template>
                    </el-table-column>
                    <el-table-column prop="fuzzySearch" label="模糊查询" width="80">
                      <template slot-scope="scope">
                        <el-switch
                          v-model="scope.row.fuzzySearch"
                          active-color="#13ce66"
                          inactive-color="#ff4949"
                          :disabled="!scope.row.searchField"
                        />
                      </template>
                    </el-table-column>
                    <el-table-column prop="isDateCol" label="日期类型" width="80">
                      <template slot-scope="scope">
                        <el-switch
                          v-model="scope.row.isDateCol"
                          active-color="#13ce66"
                          inactive-color="#ff4949"
                        />
                      </template>
                    </el-table-column>
                    <el-table-column prop="pattern" label="格式" width="160">
                      <template slot-scope="scope">
                        <el-input v-model="scope.row.pattern" autocomplete="off" size="small"
                                  placeholder="请输入日期格式" :disabled="!scope.row.isDateCol"></el-input>
                      </template>
                    </el-table-column>
                    <el-table-column
                      label="操作"
                      width="80">
                      <template slot-scope="scope">
                        <el-button size="mini" type="danger" plain @click="delProperty(scope.$index, scope.row)">删除</el-button>
                      </template>
                    </el-table-column>
                  </el-table>
                </template>
              </el-table-column>
              <el-table-column type="index" label="序号" width="100" />
              <el-table-column prop="tableName" label="表名" width="200">
                <template slot-scope="scope">
                  <el-input v-model="scope.row.tableName" autocomplete="off" size="small"
                            placeholder="表名" @change="changeJavaType(scope.$index,scope.row)"></el-input>
                </template>
              </el-table-column>
              <el-table-column prop="fieldName" label="属性名" width="200">
                <template slot-scope="scope">
                  <el-input v-model="scope.row.fieldName" autocomplete="off" size="small"
                            placeholder="属性名" @change="changeJavaType(scope.$index,scope.row)" disabled></el-input>
                </template>
              </el-table-column>
              <el-table-column prop="className" label="类名" width="200">
                <template slot-scope="scope">
                  <el-input v-model="scope.row.className" autocomplete="off" size="small"
                            placeholder="类型" @change="changeJavaType(scope.$index,scope.row)" disabled></el-input>
                </template>
              </el-table-column>
              <el-table-column prop="tableComment" label="表注释" width="200">
                <template slot-scope="scope">
                  <el-input v-model="scope.row.tableComment" autocomplete="off" size="small"
                            placeholder="表注释" @change="changeJavaType(scope.$index,scope.row)"></el-input>
                </template>
              </el-table-column>
              <el-table-column
                label="操作"
                width="200">
                <template slot-scope="scope">
                  <el-button size="mini" type="danger" plain @click="delTable(scope.$index, scope.row)">删除</el-button>
                </template>
              </el-table-column>
            </el-table>
          </el-card>
        </el-collapse-item>
      </el-card>

    </el-collapse>
  </div>
</template>
<script>
  import generate from "@/api/generate";
  export default{
    name:'TableInfo',
    props:{
      templateConfig: {
        type:Object,
        default:null
      }
    },
    data(){
      return {
        activeName:'0',
        tableList: [],
        commonProperties:[],
        acceptList:'.sql',
        uploadUrl:'',
        database:'',
        databaseType:'',
        fileList:[],
        params:new FormData(),
        databaseOptions:[
          {
            value:'mysql',
            label:'Mysql'
          },
          {
            value:'oracle',
            label:'Oracle'
          },
          {
            value:'sqlserver',
            label:'SqlServer',
            disabled:true
          },
          {
            value:'postgreSql',
            label:'PostgreSql',
            disabled:true
          }
        ],
        ruleForm:{
          database:'',
          databaseType:'',
          serialNumber:''
        },
        rules:{
          databaseType:[
            {required:true,message:'请选择数据库类型',trigger: 'blur'}
          ],
          database:[
            {required:true,message:'请输入数据库名称',trigger: 'blur'}
          ]
        }
      }
    },
    methods: {
      // 添加公共属性
      addProperty(){
        console.log('公共属性');
        let property = this.commonProperties
        console.log(property);
        let length = property.length
        this.commonProperties.push(
          {
            index:parseInt(length),
            columnName:'',
            dataType:'',
            fieldType:'',
            fieldName:'',
            defaultValue:''
          })
      },
      // 添加表格参数
      addTable(){
        console.log('表格');
        let table = this.tableList
        console.log(table);
        let length = table.length
        this.tableList.push(
          {
            index:parseInt(length),
            tableName:'',
            fieldName:'',
            className:'',
            tableComment:''
          })
      },
      // 将指定行的数据库字段变更为java类型
      changeJavaType(index,row){
        let that = this
        let property = that.commonProperties;
        for (let i = 0; i < property.length; i++) {
          if (row.index == property[i].index) {
            let item = property[i]
            item.fieldName = this.toCamelCase(item.columnName)
          }
        }
      },
      // 删除公共数据
      delProperty(index, row) {
        let that = this;
        this.$confirm('确认删除吗?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          //点击确定的操作(调用接口)
          let property = that.commonProperties;
          for (let i = 0; i < property.length; i++) {
            if (row.index == property[i].index) {
              property.splice(i, 1);
              // this.$message({ message: '删除成功', duration: 2000, type: 'success' });
            }
          }
        }).catch(() => {
          //点取消的提示
          return;
        });
      },
      delTable(index, row){
        let that = this;
        this.$confirm('确认删除吗?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          debugger
          //点击确定的操作(调用接口)
          let table = that.tableList;
          for (let i = 0; i < table.length; i++) {
            if (row.index == table[i].index) {
              table.splice(i, 1);
              // this.$message({ message: '删除成功', duration: 2000, type: 'success' });
            }
          }
        }).catch(() => {
          //点取消的提示
          return;
        });
      },
      // 下划线转驼峰
      toCamelCase(name) {
        return name.replace(/\_(\w)/g, function(all, letter){
            return letter.toUpperCase();
          }
        );
      },

      downloadFile(res){
        if(!res){
          return
        }
        const blob = new Blob([res], { type: 'application/octet-stream' }) // 构造一个blob对象来处理数据，并设置文件类型

        if (window.navigator.msSaveOrOpenBlob) { //兼容IE10
          navigator.msSaveBlob(blob, this.filename + '.zip')
        } else {
          const href = URL.createObjectURL(blob) //创建新的URL表示指定的blob对象
          const a = document.createElement('a') //创建a标签
          a.style.display = 'none'
          a.href = href // 指定下载链接
          a.download = this.filename + '.zip'//指定下载文件名
          a.click() //触发下载
          URL.revokeObjectURL(a.href) //释放URL对象
        }
        // 这里也可以不创建a链接，直接window.open(href)也能下载
      },
      // 执行生成方法
      doGenerate(){
        this.$refs['ruleForm'].validate((valid) => {
          if(valid){
            if(this.checkAndBuildParam()){
              generate.doGenerateByFile(this.params).then(res=>{
                this.downloadFile(res)
              })
              .catch(err => {
                this.$message.error('非开发角色或序列号有误，请微信联系17663702529')
              })
            }
          }else{
            return false
          }
        })
      },
      // 解析数据
      doParse: function () {
        this.$refs['ruleForm'].validate((valid) => {
          if(valid){
            if(this.checkAndBuildParam()){
              generate.parse(this.params).then(resp => {
                console.log('data', resp)
                this.$message.success('解析完成,请点击公共参数或表结构进行查看')
                this.activeName = 1
                this.commonProperties = resp.data.commonProperties
                this.tableList = resp.data.tableList
              })
            }
          }else{
            return false
          }
        })

      },
      checkAndBuildParam(){
        this.params.delete("configJson")
        this.params.append('configJson', this.getTemplateConfig())
        return this.checkFileExt()
      },
      beforeUpload(file){
        this.params = new FormData()
        this.fileList = []
        if(file){
          this.params.append('file',file); //  2. 上传之前，拿到file对象，并将它添加到刚刚定义的FormData对象中。
          this.filename = file.name
          this.fileList.push({name:file.name})
          let databaseName = this.filename.substr(0,this.filename.indexOf('.'))
          this.ruleForm.database = databaseName
          this.checkFileExt()
        }else{
          this.$message.error('文件上传失败')
          return false;
        }
      },
      // 上传错误回调
      uploadError(event,file,fileList){
        console.log(event,file,fileList)
      },
      // 删除文件回调
      handlerRemove(file,fileList){
        this.fileList = []
        this.params = new FormData()
        this.ruleForm = {}
      },
      // 校验文件
      checkFileExt(){
        if(this.filename == '' || this.filename == null){
          this.$message.error('请上传.sql文件')
          return false
        }
        if(!this.filename.endsWith('.sql')){
          this.$message.error('请上传.sql文件')
          return false
        }
        return true
      },
      getTemplateConfig(){
        let templateConfig = {
          ...this.templateConfig,
          tableList:this.tableList,
          commonProperties: this.commonProperties,
          database:this.ruleForm.database,
          databaseType:this.ruleForm.databaseType,
          serialNumber:this.ruleForm.serialNumber
        }
        return JSON.stringify(templateConfig)
      }
    }
  }
</script>
<style>
  .text {
    font-size: 14px;
  }

  .item {
    margin-bottom: 18px;
  }

  .clearfix:before,
  .clearfix:after {
    display: table;
    content: "";
  }
  .clearfix:after {
    clear: both
  }

  .box-card {
    width: 100%;
    margin-bottom: 10px;
  }
  .upload-demo,
  .el-upload,
  .el-upload__text,
  .el-upload-dragger{
    width: 100%;
  }
</style>
